import {
	Platform
} from "../platform/platform";
import {
	Utils
} from "./utils";


/**
 * 选择文件返回数据
 * */
// export interface ChooseFileResult {
// 	path: string,
// 	size: number,
// 	base64?: string,
// 	file: any,
// }

/**
 * 选择文件参数
 * */
// export interface ChooseFileOption {
// 	count?: number,
// 	sourceType?: Array<'album' | 'camera'>
// 	[key: string]: any,
// }


/**
 * 小程序选择文件参数
 * */
// export interface ChooseMediaOption {
// 	// 最多可以选择的文件个数
// 	count?: number,
// 	// 文件类型
// 	mediaType?: Array<'image'| 'video'>,
// 	// 图片和视频选择的来源
// 	sourceType?: Array<'album' | 'camera'>,
// 	// 仅对 mediaType 为 image 时有效，是否压缩所选文件
// 	sizeType?: Array<'original'| 'compressed'>,
// 	// 使用前置或后置摄像头
// 	camera?: 'back'| 'front',
// 	// 拍摄视频最长拍摄时间，单位秒。时间范围为 3s 至 30s 之间
// 	maxDuration?: number,
// }

/**
 * 选择图片参数
 * */
// export interface ChooseImageOption {
// 	// 最多可以选择的图片张数
// 	count?: number,
// 	// original 原图，compressed 压缩图
// 	sizeType?: Array<'original'| 'compressed'>,
// 	// 图片和视频选择的来源
// 	sourceType?: Array<'album' | 'camera'>
// }


const BASE64_FILE_TYPES = {
	/** 图片 */
	'jpg': 'data:image/jpeg;base64,',
	'png': 'data:image/png;base64,',
	'gif': 'data:image/gif;base64,',
	'bmp': 'data:image/bmp;base64,',
	/** 文档 */
	'txt': 'data:text/plain;base64,',
	'docx': 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,',
	'xlsx': 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,',
	'pptx': 'data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64,',
	'pdf': 'data:application/pdf;base64,',
	/** 文件 */
	'rar': 'data:text/plain;base64,',
	'zip': 'data:application/x-zip-compressed;base64,'
};

const CHOOSE_FILE_OPTION = {
	count: 1,
	// type: 'all',
	sourceType: ['album', 'camera'],
};

const CHOOSE_IMAGE_OPTION = {
	count: 1,
	sizeType: ['original', 'compressed'],
	sourceType: ['album', 'camera'],
};

const CHOOSE_MEDIA_OPTION = {
	count: 1,
	mediaType: ['image'],
	sourceType: ['album', 'camera'],
	sizeType: ['original', 'compressed'],
	camera: 'back',
	maxDuration: 30,
};

/**
 * @param {ChooseFileOption} option
 * @returns {ChooseFileResult[]}
 */
const uniChooseFile = (option) => {
	option = {
		...Utils.clone(CHOOSE_FILE_OPTION),
		...option
	};
	return new Promise((resolve) => {
		const result = [];
		uni.chooseFile({
			count: option.count,
			type: option.type,
			extension: option.extension || [],
			sourceType: option.sourceType,
			success: function(res) {
				if (Array.isArray(res.tempFiles)) {
					res.tempFiles.forEach((file) => {
						const path = file.path || '';
						const size = file.size || 0;
						result.push({
							path,
							size,
							file,
						});
					});
				}
				resolve(result);
			},
			fail: function() {
				resolve(result);
			},
		})
	});
};


/**
 * @description 文件转换base64
 * @param {string}  文件路径
 * @return {Promise<string>} 文件base64
 */
const pathToBase64 = (filePath) => {
	return new Promise((resolve) => {
		if (Platform.isH5 && typeof FileReader === 'function') {
			const xhr = new XMLHttpRequest();
			xhr.open('GET', filePath, true);
			xhr.responseType = 'blob';
			xhr.onload = function() {
				if (this.status === 200) {
					let fileReader = new FileReader();
					fileReader.onload = function(e) {
						const base64 = e.target.result;
						resolve(base64 + "");
					}
					fileReader.onerror = function(error) {};
					fileReader.readAsDataURL(this.response);
				}
			}
			xhr.onerror = function(error) {};
			xhr.send();
		}

		if (Platform.isApp) {
			plus.io.resolveLocalFileSystemURL(
				getLocalFilePath(filePath),
				function(entry) {
					entry.file(function(file) {
						var fileReader = new plus.io.FileReader()
						fileReader.onload = function(data) {
							const base64 = data.target.result;
							resolve(base64);
						}
						fileReader.onerror = function(error) {}
						fileReader.readAsDataURL(file)
					}, function(error) {})
				},
				function(error) {})
		}

		if (Platform.isMp && wx.canIUse('getFileSystemManager')) {
			const suffix = filePath.replace(/.+\.(\w+)/i, '$1');
			wx.getFileSystemManager().readFile({
				filePath,
				encoding: 'base64',
				success: function(res) {
					const base64Type = BASE64_FILE_TYPES[suffix];
					const base64 = base64Type + res.data;
					resolve(base64);
				},
				fail: function(error) {},
			});
		}
	});
};


const getLocalFilePath = (path) => {
	if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path
		.indexOf(
			'_downloads') === 0) {
		return path
	}
	if (path.indexOf('file://') === 0) {
		return path
	}
	if (path.indexOf('/storage/emulated/0/') === 0) {
		return path
	}
	if (path.indexOf('/') === 0) {
		var localFilePath = plus.io.convertAbsoluteFileSystem(path)
		if (localFilePath !== path) {
			return localFilePath
		} else {
			path = path.substr(1)
		}
	}
	return '_www/' + path
};


/**
 * @description 拍摄或从手机相册中选择图片或视频。
 * @param {ChooseMediaOption} option
 * @return {Promise<Array<{
		 path: string,
		 size: number,
	 }>>}
 */
const uniChooseMedia = (option) => {
	option = {
		...Utils.clone(CHOOSE_FILE_OPTION),
		...option
	};
	return new Promise((resolve) => {
		const result = [];
		uni.chooseMedia({
			count: option.count,
			mediaType: option.mediaType,
			sourceType: option.sourceType,
			maxDuration: option.maxDuration,
			sizeType: option.sizeType,
			camera: option.camera,
			success: function(res) {
				if (Array.isArray(res.tempFiles)) {
					res.tempFiles.forEach((tempFile) => {
						const path = tempFile.tempFilePath;
						const size = tempFile.size;
						result.push({
							path,
							size,
							file: tempFile,
						});
					});
					resolve(result);
				}
			},
			fail: function() {
				resolve([]);
			},
		})
	});
};


/**
 * @description uni.chooseImage uni 选择图片
 * @param {ChooseImageOption} option  uni.chooseImage 的参数
 * @return {Promise<Array<{
	 path: string,
	 size: string,
	 file?: File,
 }>>}
 */
const uniChooseImage = (option) => {
	option = {
		...Utils.clone(CHOOSE_IMAGE_OPTION),
		...option,
	};
	return new Promise((resolve) => {
		const result = [];
		uni.chooseImage({
			count: option.count,
			sizeType: option.sizeType,
			sourceType: option.sourceType,
			success: function(res) {
				if (Array.isArray(res.tempFiles)) {
					res.tempFiles.forEach((file) => {
						const path = file.path;
						const size = file.size;
						result.push({
							path,
							size,
							file,
						});
					});
					resolve(result);
				}
			},
			fail: function() {
				resolve([]);
			},
			complete: function() {}
		});
	});
};
/**
 * 单个文件上传
 */
const uploadFile = (url, filePath, header = {}, progressUpdateCallback = () => {}) => {
	return new Promise((resolve) => {
		const uploadTask = uni.uploadFile({
			url,
			filePath,
			header,
			name: 'file',
			// timeout: 99999999,
			formData: {},
			success: (uploadFileRes) => {
				if (uploadFileRes.statusCode === 200) {
					const result = JSON.parse(uploadFileRes.data);
					resolve(result);
				} else {
					resolve(null);
				}

			},
			fail: (error) => {
				console.log(error);
				resolve(null);
			},
		});
		uploadTask.onProgressUpdate((res) => {
			progressUpdateCallback(res);
		});
	});
};


/** 文件处理工具 */
export class FileUtils {
	/**
	 * @description 选择文件
	 * @param {ChooseFileOption} option
	 * @returns {ChooseFileResult}
	 */
	static chooseFile = async (option) => {
		let files = [];
		if (Platform.isH5) {
			files = await uniChooseFile(option);
		} else if (Platform.isWxMp) {
			option = {
				...Utils.clone(CHOOSE_MEDIA_OPTION),
				...option
			};
			files = await uniChooseMedia(option);
		} else if (Platform.isMp) {
			option = {
				...Utils.clone(CHOOSE_IMAGE_OPTION),
				...option
			};
			files = await uniChooseImage(option);
		} else if (Platform.isApp) {
			option = {
				...Utils.clone(CHOOSE_IMAGE_OPTION),
				...option
			};
			files = await uniChooseImage(option);
		}

		for (const key in files) {
			const file = files[key];
			file.base64 = await pathToBase64(file.path);
		}

		return Promise.resolve(files);
	};

	static uploadFile = uploadFile;
	/** 上传多个文件
	 * @param {ChooseFileOption} option
	 * @param {String} url 上传地址
	 * @param {Object} header 请求头部
	 * @param {ChooseFileOption} option
	 */
	static uploadFiles = async (option, url, header = {}) => {
		const files = await FileUtils.chooseFile(option);
		for (let i = 0; i < files.length; i++) {
			const file = files[i];
			const path = file.path;
			const uploadRes = await FileUtils.uploadFile(url, path, header);
		}
		return Promise.resolve(undefined);
	};
	/**
	 * 下载文件
	 */
	static downloadFile = async (url, progressCallback = () => {}) => {
		return new Promise((resolve) => {
			const downloadTask = uni.downloadFile({
				url,
				success: (res) => {
					if (res.statusCode === 200) {
						resolve(res);
					} else {
						resolve(false);
					}
				}
			});
			downloadTask.onProgressUpdate((res) => {
				progressCallback(res);
			});
		});
	};
	/**
	 * H5 下载
	 */
	static downloadFileH5 = async (url, downloadFileName = '') => {
		if (Platform.isH5 === false) {
			return Promise.resolve(undefined);
		}
		// const res = await fetch(url);
		// const blob = await res.blob();
		// const blobUrl = window.URL.createObjectURL(blob);
		if (downloadFileName) {
			const a = document.createElement('a');
			a.href = url;
			a.target = '_blank';
			a.download = downloadFileName;
			a.click();
			URL.revokeObjectURL(a.href);
		} else {
			window.open(url);
		}
		return Promise.resolve(undefined);
	};
}